/**
 * 一个并行任务执行器
 */
type TaskItem<T> = {
  task: (...args: unknown[]) => Promise<T>
  resolve: (value: T | PromiseLike<T>) => void
  reject: (reason?: unknown) => void
  index: number
  taskId: Symbol
}

class ParallelTaskExecution {
  private maxParallelCount: number; // 并行执行任务的最大数量
  private taskQueue: TaskItem<any>[]; // 任务队列
  private runningCount: number; // 正在执行的任务数量
  private taskCount: number; // 任务总数（已执行过的 + 未执行的 + 正在执行的）

  constructor(parallelCount = 2) {
    this.maxParallelCount = parallelCount
    this.taskQueue = []
    this.runningCount = 0
    this.taskCount = 0
  }

  addTask = <T>(task: (...args: unknown[]) => Promise<T>): Promise<T> => {
    return new Promise((resolve, reject) => {
      const taskItem: TaskItem<T> = {
        task,
        resolve,
        reject,
        index: this.taskCount++,
        taskId: Symbol()
      }
      this.taskQueue.push(taskItem)
      this.run()
    })
  }

  run = async () => {
    while (this.runningCount < this.maxParallelCount && this.taskQueue.length > 0) {
      const taskItem = this.taskQueue.shift()
      if (taskItem) {
        this.runningCount++
        taskItem.task().then(taskItem.resolve).catch(taskItem.reject).finally(() => {
          this.runningCount--
          this.run()
        })
      }
    }
  }
}

export default ParallelTaskExecution